package com.liyong.pullorder.sdk.exception;

/**
 * @author 葡萄味的萝卜
 * @date 2025/10/21 12:14
 * 拉单系统基础异常类
 * 核心作用：统一异常体系，提供分类处理能力
 * 设计目标：支持异常分类、重试判断、监控告警
 *
 * 异常分类：
 * - 网络异常：可重试
 * - 认证异常：需要人工干预
 * - 数据异常：部分可重试
 * - 系统异常：需要紧急处理
 */
public class PullOrderException extends RuntimeException{
    private final String errorCode;
    private final String platformCode;
    private final boolean retryable;

    public PullOrderException(String message) {
        super(message);
        this.errorCode = "SYSTEM_ERROR";
        this.platformCode = "UNKNOWN";
        this.retryable = false;
    }

    public PullOrderException(String message, String errorCode) {
        super(message);
        this.errorCode = errorCode;
        this.platformCode = "UNKNOWN";
        this.retryable = isRetryableError(errorCode);
    }

    public PullOrderException(String message, String errorCode, String platformCode) {
        super(message);
        this.errorCode = errorCode;
        this.platformCode = platformCode;
        this.retryable = isRetryableError(errorCode);
    }

    public PullOrderException(String message, Throwable cause, String errorCode, String platformCode) {
        super(message, cause);
        this.errorCode = errorCode;
        this.platformCode = platformCode;
        this.retryable = isRetryableError(errorCode);
    }

    public String getErrorCode() {
        return errorCode;
    }

    public String getPlatformCode() {
        return platformCode;
    }

    public boolean isRetryable() {
        return retryable;
    }

    /**
     * 判断错误类型是否可重试
     * 可重试错误：网络超时、服务暂时不可用、限流等
     * 不可重试错误：认证失败、参数错误、数据格式错误等
     */
    private boolean isRetryableError(String errorCode) {
        switch (errorCode) {
            case "NETWORK_TIMEOUT":
            case "SERVICE_UNAVAILABLE":
            case "RATE_LIMIT_EXCEEDED":
            case "TEMPORARY_ERROR":
                return true;
            case "AUTHENTICATION_FAILED":
            case "INVALID_PARAMETER":
            case "DATA_PARSE_ERROR":
            case "BUSINESS_ERROR":
            default:
                return false;
        }
    }
}
